#ifndef ROSTERMODEL_H
#define ROSTERMODEL_H

#include <QAbstractListModel>
#include <QQmlEngine>
#include <QQmlListProperty>
#include <QXmppPresence.h>
#include <QXmppVCardIq.h>

#include "../global/xnamespace.h"
#include "submodel/ContactModel.h"

class QQmlEngine;
class QJSEngine;

X_BEGIN_NAMESPACE

/**
 * @brief 名单。
 *
 * 名单模型在内存中保存用户的联系人列表。
 */
class RosterModel : public QAbstractListModel
{
    Q_OBJECT

signals:
    void rosterChanged(QQmlListProperty<ContactModel> contacts);  // 联系人名单变化
    void contactAdded(ContactModel& contact);
    void contactRemoved(ContactModel& contact);
    void contactUpdated(ContactModel& contact);

public:
    explicit RosterModel(QObject *parent = NULL);

    // singleton supports
    static RosterModel& instance();
    static const char* qmlName();
    static QObject* qmlInstance(QQmlEngine* engine, QJSEngine* jsEngine);

public slots:
    Q_INVOKABLE ContactModel &addContact(const QString& bareJid, const QString& groupName);
    Q_INVOKABLE ContactModel &saveContact(const QString& bareJid, const QString& photo, PhotoType photoType, const QString& groupName);
    Q_INVOKABLE void updateContactVCard(const QString& bareJid, const VCard &vcard);
    Q_INVOKABLE QObject *findContact(const QString& bareJid) const;
    Q_INVOKABLE void removeContact(const QString& bareJid);

    VCard *loadVCard(const QString& bareJid);

public:
    virtual QHash<int, QByteArray> roleNames() const override;
    virtual int rowCount(const QModelIndex &parent) const override;
    virtual QVariant data(const QModelIndex &index, int role) const override;

    void loadDataFromDb();
	void houseKeep();

private:
    static RosterModel* createInstance();
    static bool contactLessThan(const ContactModel* c1, const ContactModel* c2);

private:
    QHash<int, QByteArray> m_roleNames;
    QList<ContactModel *> m_contacts;
    QMap<QString, ContactModel *> m_contactsByBareJid;

private:
    static const char *DataRolesNames[];

    static const char READ_ROSTER[];
    static const char INSERT_CONTACT[];
    static const char UPDATE_CONTACT[];

    static const char READ_CONTACT_VCARD[];
    static const char INSERT_CONTACT_VCARD[];
    static const char UPDATE_CONTACT_VCARD[];

    static const char UPDATE_CONTACTS_GROUP[];
    static const char DELETE_CONTACT[];
};

X_END_NAMESPACE

#endif // ROSTERMODEL_H
